package com.ruicar.afs.cloud.message.sendmessage.service.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.message.sendmessage.MessageApiFeign;
import com.ruicar.afs.cloud.message.sendmessage.dto.ReturnResultInfoDto;
import com.ruicar.afs.cloud.message.sendmessage.dto.SendMessageDto;
import com.ruicar.afs.cloud.message.sendmessage.dto.SendResultInfoDto;
import com.ruicar.afs.cloud.message.sendmessage.enums.CodeTypeEnum;
import com.ruicar.afs.cloud.message.sendmessage.enums.ResultCodeEnum;
import com.ruicar.afs.cloud.message.sendmessage.enums.ResultTypeEnum;
import com.ruicar.afs.cloud.message.sendmessage.service.MessageService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: 短信/邮件发送
 * @author jiaqi.guo
 * @created 2020/8/6 22:30
 * @version 1.0
 */
@AllArgsConstructor
@Slf4j
@Service
public class MessageServiceImpl  implements MessageService {



  private MessageApiFeign messageApiFeign;
    /**
     * 短信、邮件发送
     * @param messageDto
     * @return
     */
    public SendResultInfoDto sendMessageData(SendMessageDto messageDto) {
        //组装请求报文信息
        JSONObject jsonObject = this.assemblyInfo(messageDto);
        if(ObjectUtils.isNotEmpty(jsonObject)){
            SendResultInfoDto resultInfoDto= new SendResultInfoDto();
            try{
                log.info("/******************************短信/邮件接口调用Start************************/");
                log.info(JSONObject.toJSONString(jsonObject));
                String strData=messageApiFeign.sentMessageInfo(JSONObject.toJSONString(jsonObject));
                log.info("/******************************短信/邮件接口调用End**************************/");
                if(StringUtils.isNotBlank(strData)){
                    JSONObject  object= JSONObject.parseObject(strData);
                    ReturnResultInfoDto infoDto = JSONObject.toJavaObject(object,ReturnResultInfoDto.class);
                    log.info("返回json"+object);
                    String resultCode=infoDto.getResultCode();
                    if(ResultCodeEnum.SENS_MESSAGE.getCode().equals(resultCode)
                           ||ResultCodeEnum.SEND_EMAIL.getCode().equals(resultCode)){
                       resultInfoDto.setResult(ResultTypeEnum.TRUE.getCode());
                    }else{
                       resultInfoDto.setResult(ResultTypeEnum.FALSE.getCode());
                    }
                    //发送时间戳作为唯一标识
                    resultInfoDto.setTimestamp(messageDto.getTimestamp());
                    resultInfoDto.setMsgInfo(infoDto.getResulteData());
                }

            }catch (Exception e){
                log.info("发送接调用异常，{}",e.getMessage());
                throw new AfsBaseException("发送接调用异常");
            }
          return   resultInfoDto;
        }
        return null;
    }

    /**
     * @description:组装请求报文
     * @author jiaqi.guo
     * @created 2020/8/7 12:43
     * @version 1.0
     */
    public JSONObject assemblyInfo(SendMessageDto messageDto) {
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.isNotBlank(messageDto.getCode())) {
            String signCodeMd5 = "";
            JSONArray array = new JSONArray();
            if (CollectionUtils.isNotEmpty(messageDto.getMessageDataDto())) {
                List mapList = new ArrayList();
                for (int i = 0; i < messageDto.getMessageDataDto().size(); i++) {
                    Map mapData= new HashMap();
                    if (messageDto.getCode().equals(CodeTypeEnum.MESSAGE.getCode())) {//短信消息签名组装
                        jsonObject.put("channel", messageDto.getChannel());
                        mapData.put("phone",messageDto.getMessageDataDto().get(i).getPhone());
                        mapData.put("summaryId",encode(messageDto.getMessageDataDto().get(i).getSummaryId()));
                        //estimatedTime不传默认当晚上23:59失效
                        if(StringUtils.isNotBlank(messageDto.getMessageDataDto().get(i).getEstimatedTime())){
                            mapData.put("estimatedTime",messageDto.getMessageDataDto().get(i).getEstimatedTime());
                        }
                        mapData.put("templateId",messageDto.getMessageDataDto().get(i).getTemplateId());
                        mapData.put("smsContent",messageDto.getMessageDataDto().get(i).getSmsContent());
                        mapData.put("priority",messageDto.getMessageDataDto().get(i).getPriority());
                        mapData.put("origin",messageDto.getMessageDataDto().get(i).getOrigin());
                        mapData.put("deptId",messageDto.getMessageDataDto().get(i).getDeptId());

                    } else if (messageDto.getCode().equals(CodeTypeEnum.EMAIL.getCode())) {//邮件消息签名组装
                        mapData.put("receiver",messageDto.getMessageDataDto().get(i).getReceiver());
                        mapData.put("emailContent",messageDto.getMessageDataDto().get(i).getEmailContent());
                        mapData.put("subject",messageDto.getMessageDataDto().get(i).getSubject());
                        mapData.put("priority",messageDto.getMessageDataDto().get(i).getPriority());
                        mapData.put("deptId",messageDto.getMessageDataDto().get(i).getDeptId());
                    } else {
                        throw new AfsBaseException("无发送类型code值");
                    }
                    if(!mapData.isEmpty()){
                        array.add(mapData);
                        mapList.add(mapData+"");
                    }
                }
                if(mapList.size()>0){
                    //md5加密签名
                    try {
                        log.info("需要加密字符串:"+"encrypt" + mapList.toString()+ messageDto.getTimestamp() + "encrypttamboo");
                        signCodeMd5 = encode("encrypt" + mapList.toString()+ messageDto.getTimestamp() + "encrypttamboo");
                    } catch (Exception e) {
                        throw new AfsBaseException("Md5加密异常"+e.getMessage());
                    }
                }
                jsonObject.put("uid", messageDto.getUid());
                jsonObject.put("code", messageDto.getCode());
                jsonObject.put("timestamp", messageDto.getTimestamp());
                jsonObject.put("signCode", signCodeMd5);
                jsonObject.put("data", array);
            }else{
                throw new AfsBaseException("短信内容组装参数为空");
            }
        }
        return  jsonObject;
    }
    /**
     * @description:MD5加密
     * @author jiaqi.guo
     * @created 2020/8/8 10:55
     * @version 1.0
     */
    public String encode(String password) {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            log.error("",e);
            throw new AfsBaseException("处理失败");
        }
        char[] charArray = password.toCharArray();
        byte[] byteArray = new byte[charArray.length];
        for (int i = 0; i < charArray.length; i++) {
            byteArray[i] = (byte) charArray[i];
        }
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuilder hexValue = new StringBuilder();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }
}
